﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using MySql.Data.MySqlClient;
using Services.Common;
using BartonExtension;
using SQLWrapper;
using Model.App;
using Model.Images;
using Model.Weixin;
using Model;

using Cache.Utils;
using Cache.Model;
using Cache;

namespace Services.User
{
    public class ISMUserServiceProvider : ISMServiceProvider
    {
        public const string USER_GET_INFO = "user_get_info";
        public const string USER_UPDATE_INFO = "user_update_info";
        public const string USER_GET_FRIEND_LIST = "user_get_friend_list";
        public const string USER_QUERY = "user_query";
        public override Task<ISMServiceResult> doProcess(ISMServiceModel model)
        {
            if (model.operationIdentifier.Equals(USER_GET_INFO))
            {
                Dictionary<string, object> dic = model.GetState<Dictionary<string, object>>();
                return GetUserInfo(dic["token"].ToString(), dic["userIdentifier"].ToString());
            }
            else if (model.operationIdentifier.Equals(USER_UPDATE_INFO))
            {
                ISMUpdateUserInfoRequest userinfo = model.GetState<ISMUpdateUserInfoRequest>();
                return UpdateUserInfo(userinfo);
            }
            else if(model.operationIdentifier.Equals(USER_GET_FRIEND_LIST))
            {
                Dictionary<string, object> param = model.GetState<Dictionary<string, object>>();
                Int64 uid = param["uid"].toInt64().Value;
                string token = param["token"].ToString();
                return GetUserFriendList(uid, token);
            }
            else if(model.operationIdentifier.Equals(USER_QUERY))
            {
                ISMQueryUserRequest request = model.GetState<ISMQueryUserRequest>();
                return QueryUsers(request);
            }
            return base.defaultProcess();
        }
        private Task<ISMServiceResult> GetUserFriendList(Int64 uid,string token)
        {
            return Task.Factory.StartNew<ISMServiceResult>(() =>
                {
                    ISMServiceResult result = new ISMServiceResult();

                    List<ISMFriend> friends = null;
                    if(friends == null)
                    {
                        friends = new List<ISMFriend>();
                    }
                    else
                    {
                        result.dbReturningState = friends;
                    }
                    //Load From Cache
                    MySQLOperationManager.doSQLOperationWithLoadedData(cmd =>
                        {
                            cmd.CommandText = "proc_client_get_friend_list";
                            cmd.Parameters.Add("?_uid", uid, ParameterDirection.Input);
                            cmd.Parameters.Add("?_token", token, ParameterDirection.Input);
                        },
                        e =>
                        {
                            if(e != null)
                            {
                                result.isOperationSuccess = false;
                                result.errorMsg = e;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_EXCEPTION_ERR;
                            }
                        },
                        data =>
                        {
                            if(data.Count == 1 && data.First().ContainsKey("error"))
                            {
                                result.isOperationSuccess = false;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_TOKEN_ERROR;
                                result.errorMsg = "Token验证失败";
                            }
                            else
                            {
                                data.ForEach(d =>
                                    {
                                        ISMFriend friend = new ISMFriend();
                                        if(d["a_id"].ToString().toInt64().Value == uid)
                                        {
                                            friend.isCrony = d["atob_cronyflag"].toBoolean().Value;
                                            friend.note_name = d["a_note_name"].ToString();
                                            friend.info.ID = d["b_id"].ToString().toInt64().Value;
                                            friend.info.openId = d["b_openid"].ToString();
                                            friend.info.intopenid = d["b_intopenid"].ToString();
                                            friend.info.wechatName = d["b_wechatname"].ToString();
                                            friend.info.username = d["b_name"].ToString();
                                            friend.info.sex = d["b_sex"].ToString().toEnum<Sex>();
                                            friend.info.vocation = d["b_vocation"].ToString();
                                            friend.info.occupation = d["b_occupation"].ToString();
                                            friend.info.mobile = d["b_mobile"].ToString();
                                            friend.info.telephone = d["b_telephone"].ToString();
                                            friend.info.email = d["b_email"].ToString();
                                            friend.info.officeAddress = d["b_officeaddress"].ToString();
                                            friend.info.piccardUrl = d["b_piccardUrl"].ToString();
                                            friend.info.videocardUrl = d["b_videocardUrl"].ToString();
                                            friend.info.headimgUrl = d["b_headimgUrl"].ToString();
                                        }
                                        else if(d["b_id"].ToString().toInt64().Value == uid)
                                        {
                                            friend.isCrony = d["btoa_cronyflag"].toBoolean().Value;
                                            friend.note_name = d["b_note_name"].ToString();
                                            friend.info.ID = d["a_id"].ToString().toInt64().Value;
                                            friend.info.openId = d["a_openid"].ToString();
                                            friend.info.intopenid = d["a_intopenid"].ToString();
                                            friend.info.wechatName = d["a_wechatname"].ToString();
                                            friend.info.username = d["a_name"].ToString();
                                            friend.info.sex = d["a_sex"].ToString().toEnum<Sex>();
                                            friend.info.vocation = d["a_vocation"].ToString();
                                            friend.info.occupation = d["a_occupation"].ToString();
                                            friend.info.mobile = d["a_mobile"].ToString();
                                            friend.info.telephone = d["a_telephone"].ToString();
                                            friend.info.email = d["a_email"].ToString();
                                            friend.info.officeAddress = d["a_officeaddress"].ToString();
                                            friend.info.piccardUrl = d["a_piccardUrl"].ToString();
                                            friend.info.videocardUrl = d["a_videocardUrl"].ToString();
                                            friend.info.headimgUrl = d["a_headimgUrl"].ToString();
                                        }
                                        friends.Add(friend);
                                    });
                                result.dbReturningState = friends;
                            }
                        }, CommandType.StoredProcedure, false);
                    return result;
                });
        }
        private Task<ISMServiceResult> UpdateUserInfo(ISMUpdateUserInfoRequest user)
        {
            return Task.Factory.StartNew<ISMServiceResult>(() =>
            {
                ISMServiceResult result = new ISMServiceResult();
                MySQLOperationManager.doSQLOperation(cmd =>
                {
                    cmd.CommandText = "proc_client_update_userinfo";
                    cmd.Parameters.Add("?_uid", user.userinfo.ID, ParameterDirection.Input);
                    cmd.Parameters.Add("?_openid", user.userinfo.openId, ParameterDirection.Input);
                    cmd.Parameters.Add("?_intopenid", user.userinfo.intopenid, ParameterDirection.Input);
                    cmd.Parameters.Add("?_wechatName", user.userinfo.wechatName, ParameterDirection.Input);
                    cmd.Parameters.Add("?_username", user.userinfo.username, ParameterDirection.Input);
                    cmd.Parameters.Add("?_sex", user.userinfo.sex, ParameterDirection.Input);
                    cmd.Parameters.Add("?_vocation", user.userinfo.vocation, ParameterDirection.Input);
                    cmd.Parameters.Add("?_company", user.userinfo.company, ParameterDirection.Input);
                    cmd.Parameters.Add("?_occupation", user.userinfo.occupation, ParameterDirection.Input);
                    cmd.Parameters.Add("?_mobile", user.userinfo.mobile, ParameterDirection.Input);
                    cmd.Parameters.Add("?_telephone", user.userinfo.telephone, ParameterDirection.Input);
                    cmd.Parameters.Add("?_email", user.userinfo.email, ParameterDirection.Input);
                    cmd.Parameters.Add("?_officeAddr", user.userinfo.officeAddress, ParameterDirection.Input);
                    cmd.Parameters.Add("?_piccardUrl", user.userinfo.piccardUrl, ParameterDirection.Input);
                    cmd.Parameters.Add("?_videocardUrl", user.userinfo.videocardUrl, ParameterDirection.Input);
                    cmd.Parameters.Add("?_headimgurl", user.userinfo.headimgUrl, ParameterDirection.Input);
                    cmd.Parameters.Add("?_token", user.token, ParameterDirection.Input);
                    cmd.Parameters.Add("?_last_access_id", MySqlDbType.Int64, ParameterDirection.Output);
                    cmd.Parameters.Add("?errorcode", MySqlDbType.Int32, ParameterDirection.Output);
                    cmd.ExecuteNonQuery();
                    int errorcode = cmd.Parameters["?errorcode"].Value.toInt32().Value;
                    if (errorcode == -1)
                    {
                        result.isOperationSuccess = false;
                        result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_TOKEN_ERROR;
                        result.errorMsg = "Token验证非法";
                    }
                    else if(errorcode == 0)
                    {
                        if(user.userinfo.ID <= 0)
                        {
                            user.userinfo.ID = cmd.Parameters["?_last_access_id"].Value.toInt64().Value;
                        }
                        result.dbReturningState = user.userinfo;

                        if(CacheManager.instance.doCacheObject<ISMUserinfo>(user.userinfo,user.userinfo.intopenid).isSuccessCached)
                        {

                        }
                    }
                },
            e =>
            {
                if (e != null)
                {
                    result.isOperationSuccess = false;
                    result.errorMsg = e;
                    result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_EXCEPTION_ERR;
                }
            }, CommandType.StoredProcedure, false);
                return result;
            });
        }
        private Task<ISMServiceResult> GetUserInfo(string token, string userIdentifier)
        {
            return Task.Factory.StartNew<ISMServiceResult>(() =>
            {
                ISMServiceResult result = new ISMServiceResult();
                MySQLOperationManager.doSQLOperationWithLoadedData(cmd =>
                {
                    cmd.CommandText = "proc_client_get_userinfo";
                    cmd.Parameters.Add("?_token", token, ParameterDirection.Input);
                    cmd.Parameters.Add("?_intopenid", userIdentifier, ParameterDirection.Input);
                },
                e =>
                {
                    if (e != null)
                    {
                        result.isOperationSuccess = false;
                        result.errorMsg = e;
                    }
                },
                data =>
                {
                    if (data.Count == 1 && data.First().ContainsKey("error"))
                    {
                        result.isOperationSuccess = false;
                        result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_TOKEN_ERROR;
                        result.errorMsg = "Token验证非法";
                        return;
                    }
                    if (data.Count > 0)
                    {
                        var userInfo = data.First();
                        ISMUserinfo ismuserinfo = new ISMUserinfo()
                        {
                            ID = userInfo["ID"].ToString().toInt64().Value,
                            openId = userInfo["openid"].ToString(),
                            intopenid = userInfo["intopenid"].ToString(),
                            wechatName = userInfo["wechatname"].ToString(),
                            username = userInfo["username"].ToString(),
                            sex = (Sex)userInfo["sex"].ToString().toInt32().Value,
                            vocation = userInfo["vocation"].ToString(),
                            company = userInfo["company"].ToString(),
                            occupation = userInfo["occupation"].ToString(),
                            mobile = userInfo["mobile"].ToString(),
                            telephone = userInfo["telephone"].ToString(),
                            email = userInfo["email"].ToString(),
                            officeAddress = userInfo["officeaddress"].ToString(),
                            piccardUrl = userInfo["piccardUrl"].ToString(),
                            videocardUrl = userInfo["piccardUrl"].ToString(),
                            headimgUrl = userInfo["headimgUrl"].ToString()
                        };
                        result.dbReturningState = ismuserinfo;
                    }
                    else
                    {
                        result.isOperationSuccess = false;
                        result.errorMsg = "该openid未注册";
                        result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_USER_OPENID_NOT_EXISTS;
                    }
                }, CommandType.StoredProcedure, false);
                return result;
            });
        }
        private Task<ISMServiceResult> QueryUsers(ISMQueryUserRequest request)
        {
            return Task.Factory.StartNew<ISMServiceResult>(() =>
                {
                    ISMServiceResult result = new ISMServiceResult();
                    MySQLOperationManager.doSQLOperationWithLoadedData(cmd =>
                        {
                            cmd.CommandText = "proc_client_query_users";
                            cmd.Parameters.Add("?_query", request.query, ParameterDirection.Input);
                            cmd.Parameters.Add("?_queryType", request.queryType, ParameterDirection.Input);
                            cmd.Parameters.Add("?startIdx", request.page * request.pageSize, ParameterDirection.Input);
                            cmd.Parameters.Add("?endIdx", (request.page+1) * request.pageSize, ParameterDirection.Input);
                            cmd.Parameters.Add("?_token", request.token, ParameterDirection.Input);
                        },
                        e =>
                        {
                            if(e!= null)
                            {
                                result.isOperationSuccess = false;
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_EXCEPTION_ERR;
                                result.errorMsg = e;
                            }
                        },
                        data =>
                        {
                            if(data.Count == 1 && data.First().ContainsKey("error"))
                            {
                                result.isOperationSuccess = false;
                                result.errorMsg = "Token 验证非法";
                                result.errorCode = ISMServiceResultErrorCodes.ERR_CODE_ISM_TOKEN_ERROR;
                            }
                            else
                            {
                                List<ISMUserinfo> matchedUsers = new List<ISMUserinfo>();
                                data.ForEach(userInfo =>
                                    {
                                        ISMUserinfo ismuserinfo = new ISMUserinfo()
                                        {
                                            ID = userInfo["ID"].ToString().toInt64().Value,
                                            openId = userInfo["openid"].ToString(),
                                            intopenid = userInfo["intopenid"].ToString(),
                                            wechatName = userInfo["wechatname"].ToString(),
                                            username = userInfo["username"].ToString(),
                                            sex = (Sex)userInfo["sex"].ToString().toInt32().Value,
                                            vocation = userInfo["vocation"].ToString(),
                                            company = userInfo["company"].ToString(),
                                            occupation = userInfo["occupation"].ToString(),
                                            mobile = userInfo["mobile"].ToString(),
                                            telephone = userInfo["telephone"].ToString(),
                                            email = userInfo["email"].ToString(),
                                            officeAddress = userInfo["officeaddress"].ToString(),
                                            piccardUrl = userInfo["piccardUrl"].ToString(),
                                            videocardUrl = userInfo["piccardUrl"].ToString(),
                                            headimgUrl = userInfo["headimgUrl"].ToString()
                                        };
                                        matchedUsers.Add(ismuserinfo);
                                    });
                                result.dbReturningState = matchedUsers;
                            }
                        }, CommandType.StoredProcedure, false);
                    return result;
                });
        }
    }
}
